// #include "sem.hpp"
#include "sem_v2.hpp"
#include <iostream>
#include <cstdio>
#include <unistd.h>
#include <ctime>
#include <sys/wait.h>
using namespace std;

int main()
{
    srand(time(0) ^ getpid());
    //-----v1--------
    // SemBuider sb;
    // auto fsem = sb.setVal(1).buid(SEM_FLAG_BUID, 1);

    //-----v2--------
    //基于建造者模式接口实例化具体建造者对象
    std::shared_ptr<SemaphoreBuilder> builder = make_shared<ConstructBuilder>();
    //在指导者的帮助下构建产品
    std::shared_ptr<Director> derictor = std::make_shared<Director>();
    derictor->construct(builder, SEM_FLAG_BUID, 3, 0660, {1,2,3});

    //父进程获取信号量对象
    cout<<"父进程id"<<getpid()<<"获取信号量对象"<<endl;
    auto fsem = builder->getSemaphore();

    pid_t pid = fork();
    if (pid < 0)
    {
        cerr << "fork error: " << strerror(errno) << endl;
        return -1;
    }
    else if (pid == 0) // child
    {

        //cout<<"进入子进程"<<endl;

        //子进程获取信号量对象
        derictor->construct(builder, SEM_FLAG_GET);
        auto csem = builder->getSemaphore();
        int cnt = 20;
        while (cnt--)
        {
            csem->P(0);
            printf("%c", 'A');
            fflush(stdout);
            usleep(rand() % 55515);
            printf("%c", 'A');
            fflush(stdout);
            usleep(rand() % 44144);
            csem->V(0);
        }
    }
    int cnt = 50;
    while (cnt--)
    {
        usleep(1000);
       // cout<<"进入主进程"<<endl;
        fsem->P(0);
        printf("%c", 'b');
        fflush(stdout);
        usleep(rand() % 55155);
        printf("%c", 'B');
        fflush(stdout);
        usleep(rand() % 44414);
        fsem->V(0);
    }
    waitpid(pid, nullptr, 0);

    return 0;
}